﻿using Inovout.Cloud.Applications.Models;
using Inovout.Cloud.Applications.Security.Models;
using Inovout.Cloud.Models;
using Inovout.Cloud.Repositories;
using Inovout.Models;
using Inovout.Security;
using Inovout.Security.Services;
using Inovout.Services;
using NHibernate.Criterion;
using System.Collections.Generic;
using System.Threading;

namespace Inovout.Cloud.Services
{
    public class ProjectService : RepositoryService<Project>, IProjectService
    {
        public Project FindByName(string name)
        {
            return base.Repository.Find(Restrictions.Eq("Name", name).IgnoreCase());
        }

        public override void Create(Project project)
        {
            Application application = new Application();
            if (Thread.CurrentPrincipal.Identity.IsAuthenticated)
            {
                application.Membership = project.Membership = base.Membership;
            }
            else
            {
                //解决在非界面创建问题
                application.Membership = project.Membership;
            }
            
            application.Name = project.Name;

            ApplicationUser applicationUser = new ApplicationUser();
            applicationUser.Application = application;
            applicationUser.Name = project.Name;
            
            //applicationUser.OwnerUser = project.Membership.User;
            application.ApplicationUser = applicationUser;
            ComponentRegistry.Resolve<IRepositoryService<ApplicationUser>>().Save(applicationUser);

            project.Applications.Add(application);
            base.Create(project);
           
        }

        public IList<Project> FindByCurrentMembership()
        {
            return base.Repository.FindAll(Restrictions.Eq("Membership.Id", ((DataObject)Membership).Id));
        }

        public void ChangeProduct(Project project, Product product, bool enable)
        {
            if (enable)
            {
                project.Products.Add(product);
               
            }
            else
            {
                project.Products.Remove(product);
            }
            base.Repository.Save(project);

            if (enable)
            {
                CreateProductPermissons(project, product);

            }
            else
            {
                RemoveProductPermissons(project, product);
            }
        }

        private void CreateProductPermissons(Project project,Product product)
        {
            //appuser
            ApplicationUser appUser = null;
            foreach (var application in project.Applications)
            {
                if (application.ApplicationUser != null)
                {
                    appUser = application.ApplicationUser;
                    break;
                }
            }
            //product
            IRepositoryService<Permission> repPermisson = ComponentRegistry.Resolve<IRepositoryService<Permission>>();
           
            //激活
            if (null == project.Products)
            {
                project.Products = new HashSet<Product>();
            }
   
            //permisson
            foreach (var application in product.Applications)
            {
                foreach (var api in application.ApplicationInterfaces)
                {
                    foreach (var privilege in api.Privileges)
                    {
                        Permission permisson = new Permission();
                        permisson.Privilege = privilege;
                        permisson.Actor = appUser;
                        repPermisson.Save(permisson);
                    }
                }
            }
        }

        private void RemoveProductPermissons(Project project, Product product)
        {
            //appuser
            ApplicationUser appUser = null;
            foreach (var application in project.Applications)
            {
                if (application.ApplicationUser != null)
                {
                    appUser = application.ApplicationUser;
                    break;
                }
            }
            //product
            PermissionService repPermisson = ComponentRegistry.Resolve<PermissionService>();  
            //permisson
            foreach (var application in product.Applications)
            {
                foreach (var api in application.ApplicationInterfaces)
                {      
                    foreach (var privilege in api.Privileges)
                    {
                        Permission permisson = repPermisson.FindByActorAndPrivilege(appUser, privilege);
                        repPermisson.Delete(permisson.Id);
                    }
                }
            }
        }


        protected ProjectRepository ProjectRepository
        {
            get { return (ProjectRepository)base.Repository; }
        }

        public Project FindByApplication(Application application)
        {
            return ProjectRepository.FindByApplication(application);
        }
    }
}
